#include <surface\coonsSurface.h>
#include <surface\coonsPolynom.h>

#include <base\global.h>

#include <iostream>
#include <iomanip>
#include <cmath>

void 
coonsSurface::addControlHeight(int row_index, int ritem, double height) {
  control_heights[row_index][ritem] = height;
}

double
coonsSurface::getControlHeight(int row_index, int ritem) {
  return control_heights[row_index][ritem];
}

double **
coonsSurface::getCoonsHeights() {
  return coons_heights;
}

void
coonsSurface::computeSurface(vec2i res) {

  double height;

  if (coons_heights && surface_resolution != res) {
    for (int col = 0; col != abs(surface_resolution[0]); col++) {
      delete [] coons_heights[col];
    }

    delete [] coons_heights;
    coons_heights = NULL;
  }

  if (!coons_heights) {
    surface_resolution = res;
    coons_heights = new double *[abs(res[0])];
    for (int col = 0; col != abs(res[0]); col++) {
      coons_heights[col] = new double[abs(res[1])];
    }
  }

  for (int r = 0; r < abs(res[0]); r += 1) {
    for (int s = 0; s < abs(res[1]); s += 1) {
   
      height = 0.0;
      for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
          double cp1 = coonsPolynom::compute(i, (float) r / (float) res[0]);
          double cp2 = coonsPolynom::compute(j, (float) s / (float) res[1]);
          double increment = control_heights[i][j] * cp1 * cp2;
          height += increment;
        }
      }

      coons_heights[r][s] = height;
    }
  }
}

coonsSurface::coonsSurface() {
   coons_heights = NULL;

   for (int cp = 0; cp != 4; cp++) {
     control_heights[cp] = new double[4];
   }
}

coonsSurface::~coonsSurface() {
  for (int cp = 0; cp != 4; cp++) {
    delete [] control_heights[cp];
  }
}